#! /bin/env python

import sys
import os
from bottle import ( run, route, debug, redirect, abort, template, view, request,
                    get, post, static_file, TEMPLATE_PATH )

from ..libmoops import debug_print, config, TEXT_ADDRESS, DATA_ADDRESS
from ..emulator import cpu
from ..translator import translator

debug(config.getboolean('global','debug'))

if hasattr(sys, "frozen"):
    BASE_PATH = os.path.abspath(os.path.dirname(sys.executable))
else:
    BASE_PATH = os.path.abspath(os.path.dirname(__file__))

STATIC_PATH = os.path.join(BASE_PATH,'static')
TEMPLATE_PATH.append(os.path.join(BASE_PATH,'views'))

CPU = cpu.cpu()
CPU.output=''
CPU.initializePipeline()

@get('/')
def display():
    if CPU.getInstruction(CPU.pc) == 0xc:
        redirect('/syscall')
    
    mem=sorted(CPU.memory.kuser.items())
    if DATA_ADDRESS in CPU.memory.kuser:
        first_dat = mem.index((DATA_ADDRESS, CPU.memory.kuser[DATA_ADDRESS]))
    else:
        first_dat = len(mem)
    txt, dat = mem[:first_dat], mem[first_dat:]
    
    dat = "<br>".join("0x%08x | 0x%08x"%(k, v) for k, v in sorted(dat))
    txt = "<br>".join("0x%08x | 0x%08x"%(k, v) for k, v in sorted(txt))
    pc_inst="0x%08x 0x%08x"%(CPU.pc, CPU.getInstruction(CPU.pc))
    reg=["0x%08x"%i for i in CPU.register.getRegisterState()]
    return template('moops', txt=txt, dat=dat, pc_inst=pc_inst, reg=reg, out=CPU.output)

@get('/set/:reg/:val')
def set_reg(reg, val):
    reg=int(reg)
    if reg > 31 or reg == 0:
        abort(403, "Illegal register number!")
    CPU.register.register[reg]=int(val)
    redirect('/')

@get('/static/:filename')
def server_static(filename):
    return static_file(filename, root=STATIC_PATH)

@get('/step')
def step():
    CPU.fiveStageStep()
    redirect('/')


@post('/upload')
def do_upload():
    name = request.forms.get('name')
    data = request.files.get('data')
    debug_print(name, data)
    if data is not None:
        CPU.initializePipeline()
        #CPU.memory.clear()
        CPU.loadBinary(translator.make_binary(data.file.read()), False)
    redirect('/')

@get('/input/:type_')
def input_form(type_):
    return template('input', type_=type_)

@post('/inp/int')
def inp_int():
    data = request.forms.get('data')
    CPU.register[translator.reg_names.index('a0')]=int(data)
    redirect('/step')

@post('/inp/string')
def inp_string():
    #TODO: make this work
    data = request.forms.get('data')
    redirect('/step')

@get('/syscall')
def syscall():
    call_code = CPU.register.register[translator.reg_names.index('v0')]
    debug_print("SYSCALL number %i: " % call_code )
    if call_code == 1:
        CPU.output += CPU.register[translator.reg_names.index('a0')] + '\n'
    elif call_code == 4:
        ##TODO: print some stringage
        pass
    elif call_code == 5:
        redirect('/input/int')
    elif call_code == 8:
        redirect('/input/string')
    else:
        raise NotImplementedError
    redirect('/step')
